import {Button, Checkbox, Form, Input, InputRef, Popconfirm, Table} from 'antd';
import React, {useContext, useEffect, useImperativeHandle, useRef, useState} from 'react';
import {FormInstance} from 'antd/lib/form';
import {uuid} from '@antv/x6/es/util/string/uuid';

const EditableContext = React.createContext<FormInstance<any> | null>(null);

interface EditableRowProps {
  index: number;
}

const EditableRow = (props: any) => {
  const {saveForm, ...resProps} = props;
  const [form] = Form.useForm();
  useEffect(() => {
    saveForm?.(form);
  }, [])

  return (
    <Form form={form} component={false}>
      <EditableContext.Provider value={form}>
        <tr {...resProps} />
      </EditableContext.Provider>
    </Form>
  );
};

interface EditableCellProps {
  title: React.ReactNode;
  editable: boolean;
  children: React.ReactNode;
  dataIndex: string;
  record: any;
  handleSave: (record: any) => void;
}

const EditableCell: React.FC<EditableCellProps> = (
  {
    title,
    editable,
    children,
    dataIndex,
    record,
    handleSave,
    ...restProps
  }) => {
  const [editing, setEditing] = useState(false);
  const inputRef = useRef<InputRef>(null);
  const form = useContext(EditableContext)!;

  useEffect(() => {
    form.setFieldsValue({[dataIndex]: record?.[dataIndex]});
  }, [record]);

  const save = async () => {
    try {
      const values = await form.validateFields();
      handleSave({...record, ...values});
    } catch (errInfo) {
      console.log('Save failed:', errInfo);
    }
  };

  let childNode = children;

  if (editable) {
    childNode = dataIndex === 'isDefault' ? (
      <Form.Item
        style={{margin: 0}}
        name={dataIndex}
        valuePropName={'checked'}
        rules={[
          {
            required: true,
            message: `${title}必填.`,
          },
        ]}
      >
        <Checkbox onChange={save}/>
      </Form.Item>
    ) : (
      <Form.Item
        style={{margin: 0}}
        name={dataIndex}
        rules={[
          {
            required: true,
            message: `${title}必填.`,
          },
        ]}
      >
        <Input ref={inputRef} onPressEnter={save} onBlur={save}/>
      </Form.Item>
    );
  }

  return <td {...restProps}>{childNode}</td>;
};

type EditableTableProps = Parameters<typeof Table>[0];

type ColumnTypes = Exclude<EditableTableProps['columns'], undefined>;

const WTableSetting = React.forwardRef((props: any, ref: any) => {
  const {value = []} = props;
  const [dataSource, setDataSource] = useState<any[]>([]);
  const [formList, setFormList] = useState<any[]>([])

  useImperativeHandle(ref, () => ({
    formList,
  }));

  useEffect(() => {
    setDataSource(value.map((item: any, index: number) => {
      return {...item, key: uuid()};
    }));
  }, [value]);

  const handleDelete = (key: React.Key) => {
    const newData = dataSource.filter(item => item.key !== key);
    setDataSource(newData);
    formList.splice(Number(key), 1);
    setFormList([...formList]);
  };

  const defaultColumns: (ColumnTypes[number] & { editable?: boolean; dataIndex: string })[] = [
    {
      title: '显示名称',
      dataIndex: 'name',
      editable: true,
    },
    {
      title: 'value值',
      dataIndex: 'code',
      editable: true,
    },
    {
      title: '设置缺省',
      dataIndex: 'isDefault',
      editable: true,
    },
    {
      title: '操作',
      dataIndex: 'operation',
      render: (_: any, record: any) =>
        dataSource.length >= 1 ? (
          <Popconfirm title="确定要删除吗?" onConfirm={() => handleDelete(record.key)}>
            <a>删除</a>
          </Popconfirm>
        ) : null,
    },
  ];

  const handleAdd = () => {
    const newData = {
      key: uuid(),
      name: '',
      code: '',
      isDefault: false,
    };
    setDataSource([...dataSource, newData]);
  };

  const handleSave = (row: any) => {
    const newData = [...dataSource];
    const index = newData.findIndex(item => row.key === item.key);
    const item = newData[index];
    newData.splice(index, 1, {
      ...item,
      ...row,
    });
    setDataSource(newData);
  };

  const components = {
    body: {
      row: EditableRow,
      cell: EditableCell,
    },
  };

  const columns = defaultColumns.map(col => {
    if (!col.editable) {
      return col;
    }
    return {
      ...col,
      onCell: (record: any) => ({
        record,
        editable: col.editable,
        dataIndex: col.dataIndex,
        title: col.title,
        handleSave
      }),
    };
  });

  // @ts-ignore
  return (
    <div>
      <Button onClick={handleAdd} type="primary" style={{marginBottom: 16}}>
        添加
      </Button>
      <Table
        components={components}
        rowClassName={() => 'editable-row'}
        bordered
        rowKey={'key'}
        dataSource={dataSource}
        columns={columns as ColumnTypes}
        onRow={record => {
          return {
            onClick: event => {},
            saveForm: (event: any) => {
              setFormList((formList) => [...formList, event])
            },
          };
        }}
      />
    </div>
  );
});

export default WTableSetting;
